package com.weed.table.rowhead;

import java.awt.event.MouseEvent;
import javax.swing.table.TableColumn;
import javax.swing.JViewport;
import java.beans.PropertyChangeEvent;
import javax.swing.event.ChangeEvent;

import java.awt.Container;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import javax.swing.table.TableColumnModel;
import javax.swing.JComponent;
import java.awt.Rectangle;
import java.beans.PropertyChangeListener;
import javax.swing.JScrollPane;

import java.awt.Point;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.JTable;
import javax.swing.UIDefaults.ProxyLazyValue;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

/**设定行头显示的组件。*/
public class RowHeadComponent extends JTable implements PropertyChangeListener,
        ListSelectionListener,MouseListener,MouseMotionListener{
    private JTable table = null;
    private TableColumn tableColumn = new TableColumn(0, 17);
    private int fixupedColumnCount = 0;
    private Cursor cursor = null;
    /**设置table显示的行头。*/
    public RowHeadComponent(JTable table) {
        this.table = table;
        setAutoCreateColumnsFromModel(false);
        setModel(table.getModel());
        RowHeadTableCellRenderer rhtc = new RowHeadTableCellRenderer();//行头绘制
        tableColumn.setCellRenderer(rhtc);//设置列的绘制者。
        setSelectionModel(table.getSelectionModel());
        table.addPropertyChangeListener(this);
        this.setRowMargin(2);
        installListener();
        this.getTableHeader().setReorderingAllowed(false);
      }
 /**
     * 提供黙认的绘制者为渐进色。
     */
    protected void createDefaultRenderers() {
        super.createDefaultRenderers();
        //黙认的绘制者。
        defaultRenderersByColumnClass.put(Object.class,
                new ProxyLazyValue("com.weed.table.renderer.ColorRenderer"));
    }
    /**设置行(row)和列(column)指定的单无格不可编辑。*/
    public boolean isCellEditable(int row, int column) {
        return false;
    }

    /**获得行头的高。*/
    public int getRowHeight() {
        if (table == null)
            return super.getRowHeight();
        return table.getRowHeight();
    }

    /**获得行头的高。*/
    public int getRowHeight(int row) {
        if (table == null)
            return super.getRowHeight(row);
        return table.getRowHeight(row);
    }

    /**获得行头背景色。*/
    public Color getSelectionBackground() {
        if (table == null)
            return super.getSelectionBackground();
        return table.getSelectionBackground();
    }

    /**获得行头的前景色。*/
    public Color getSelectionForeground() {
        if (table == null)
            return super.getSelectionForeground();
        return table.getSelectionForeground();
    }

    /**获得指定的行(row)和列(column)的Rectangle值。*/
    public Rectangle getCellRect(int row, int column, boolean includeSpacing) {
        if (table == null)
            return super.getCellRect(row, column, includeSpacing);
        Rectangle r = new Rectangle();
        boolean valid = true;
        if (row < 0) {
            // y = height = 0;
            valid = false;
        } else if (row >= getRowCount()) {
            r.y = getHeight();
            valid = false;
        } else {
            r.height = getRowHeight(row);
            r.y = table.getCellRect(row, 0, includeSpacing).y;
        }

        if (column < 0) {
            // x = width = 0;
            valid = false;
        } else if (column >= getColumnCount()) {
            r.x = getWidth();
            valid = false;
        } else {
            TableColumnModel cm = getColumnModel();
            for (int i = 0; i < column; i++) {
                r.x += cm.getColumn(i).getWidth();
            }
            r.width = cm.getColumn(column).getWidth();
        }

        if (valid && !includeSpacing) {
            int rm = getRowMargin();
            int cm = getColumnModel().getColumnMargin();
            // This is not the same as grow(), it rounds differently.
            r.setBounds(r.x + cm / 2, r.y + rm / 2, r.width - cm, r.height - rm);
        }
        return r;
    }

    /**指定一个点所处的行的位置。*/
    public int rowAtPoint(Point point) {
        if (table == null)
            return super.rowAtPoint(point);
        return table.rowAtPoint(point);
    }

    /**设置行高。*/
    public void setRowHeight(int height) {
        if (table == null)
            return;
        else
            table.setRowHeight(height);
    }

    /**设置指定行的高度。*/
    public void setRowHeight(int row, int height) {
        if (table == null)
            return;
        else
            table.setRowHeight(row, height);
    }

    /**当行头的列宽度发生改变,设置表格的大小发生变化。*/
    public void columnMarginChanged(ChangeEvent e) {
        super.columnMarginChanged(e);
        Container parent = getParent();
        if (parent != null && parent instanceof JComponent) {
            ((JComponent) parent).setPreferredSize(new Dimension(
                    getColumnModel().getTotalColumnWidth(),
                    (int) parent.getPreferredSize().getHeight()));
        }
    }

    /**用于在行头前添加列。*/
    public void fixuped(int count) {
        getColumnModel().removeColumn(tableColumn);
        if (count <= 0) {
            getColumnModel().addColumn(tableColumn);
            getColumnModel().moveColumn(getColumnCount() - 1, 0);
//            setRowMargin(1);
//            getColumnModel().setColumnMargin(1);
        } else {
            getColumnModel().addColumn(tableColumn);
            if (count > table.getColumnCount() - 1)
                count = table.getColumnCount() - 1;
            TableColumnModel tempColumnModel = table.getColumnModel();
            for (int i = 0; i < count; i++) {
                TableColumn tempColumn = tempColumnModel.getColumn(0);
                tempColumnModel.removeColumn(tempColumn);
                getColumnModel().addColumn(tempColumn);

            }
            setRowMargin(1);
            getColumnModel().setColumnMargin(1);
        }

        Container p = table.getParent();
        if (p != null && p instanceof JViewport) {
            p = p.getParent();
            if (p != null && p instanceof JScrollPane) {
                JScrollPane sp = (JScrollPane) p;
                sp.setRowHeaderView(this);
                sp.getRowHeader().setPreferredSize(new Dimension(getColumnModel().
                        getTotalColumnWidth(),
                        (int) sp.getRowHeader().getPreferredSize().getHeight()));
            }
        }
    }


    public void propertyChange(PropertyChangeEvent evt) {
        if (evt.getPropertyName().equals("model")) {
            this.setModel(table.getModel());
        }
    }

    /**当行头获得焦点时，将焦点转移到行头上。*/
    private void installListener() {
        this.setSelectionModel(table.getSelectionModel());
        this.getSelectionModel().addListSelectionListener(this);
        this.addMouseListener(this);
        this.addMouseMotionListener(this);
    }
    public void valueChanged(ListSelectionEvent event){
            int[] rows = this.getSelectedRows();
            for(int i=0;i<rows.length;i++){
                    table.addRowSelectionInterval(rows[0], rows[0]);
            }
            this.repaint();
    }

    public void mouseClicked(MouseEvent e) {}
    int pointy = 0;
    int height = 0;
    int selectrow = -1;
    public void mousePressed(MouseEvent e) { 
        if(isDrog){
            pointy = e.getY();
            height = this.getRowHeight(selectrow);
        }
    }

    public void mouseReleased(MouseEvent e) {}

    public void mouseEntered(MouseEvent e) {}

    public void mouseExited(MouseEvent e) {}

    public void mouseDragged(MouseEvent e) {
        if(isDrog){
            int _height = e.getY()-pointy + height;
            if(_height <5)_height = 5;
            if(_height >1000)_height = 1000;
            this.setRowHeight(selectrow, _height);
            table.setRowHeight(selectrow,_height);            
            this.repaint();
        }
    }
    boolean isDrog = false;
    
    public void mouseMoved(MouseEvent e) {
        int rows = this.rowAtPoint(e.getPoint());
        int sizeRows = 0;
        int lastRowHeight=0;
        for(int i=0;i<=rows; i++){
            lastRowHeight = this.getRowHeight(i);
            sizeRows += lastRowHeight;
        }
        if(((sizeRows - e.getY())<=2 || ((sizeRows - lastRowHeight)+2) >= e.getY())){
            this.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
            isDrog = true;
            if((sizeRows - e.getY())<=2)
                this.selectrow = rows;
            else if(((sizeRows - lastRowHeight)+2) >= e.getY()){
                this.selectrow = rows -1;
            }
        }else{
            this.setCursor(Cursor.getDefaultCursor());
            isDrog = false;
        }
        
    }
}
